#ifndef AVALON_TCPSOCKETREADER_HPP
#define AVALON_TCPSOCKETREADER_HPP
#include <boost/enable_shared_from_this.hpp>
#include "Avalon/IO/Reader.hpp"
#include "Avalon/Network/Network.hpp"

namespace boost {
namespace system {
  class error_code;
}
}

namespace Avalon {
namespace Network {

  /*! \class TcpSocketReader
   *  \brief Reads from a socket.
   *  \author Kamal Mansouri <kranar@hotmail.com>
   */
  class TcpSocketReader : public IO::Reader,
      public boost::enable_shared_from_this<TcpSocketReader> {
    public:

      virtual ~TcpSocketReader();

      virtual bool IsAtEndOfDataSource();

      virtual Threading::Async<int>::Ptr Read(IO::Buffer* destination);

      virtual Threading::Async<int>::Ptr Read(void* destination, int size);

      virtual Threading::Async<int>::Ptr Read(IO::Buffer* destination,
        int size);

    private:
      friend class TcpServerSocket;
      friend class TcpClientSocketChannel;
      friend class TcpSocketConnection;
      boost::recursive_mutex m_mutex;
      boost::shared_ptr<Detail::SocketType> m_socket;
      Threading::AsyncOwner<int>::Ptr m_readResult;

      TcpSocketReader(const boost::shared_ptr<Detail::SocketType>& socket);
      void Abort();
      void HandleRead(void* destination, int readSize,
        const boost::system::error_code& error, size_t size);
  };
}
}

#endif // AVALON_TCPSOCKETREADER_HPP
